<template>
  <div class="process-toolbar">
    <div class="toolbar-container">
      <!-- 使用 Element Plus 按钮组优化文件操作按钮 -->
      <el-button-group class="toolbar-button-group">
        <el-button
          type="primary"
          size="small"
          @click="handleCommand('import')"
          :icon="FolderOpened">
          导入
        </el-button>
        <input
          type="file"
          ref="fileInput"
          style="display: none"
          accept=".bpmn,.xml"
          @change="handleFileChange" />
        <el-button
          type="primary"
          size="small"
          @click="handleCommand('download')"
          :icon="Download">
          导出
        </el-button>
        <el-button
          type="primary"
          size="small"
          @click="handleCommand('preview')"
          :icon="Monitor">
          预览
        </el-button>
        <el-button
          type="primary"
          size="small"
          @click="handleCommand('validate')"
          :icon="Check">
          校验
        </el-button>
        <el-button
          type="primary"
          size="small"
          @click="handleCommand('save')"
          :icon="Document">
          保存
        </el-button>
      </el-button-group>

      <div class="toolbar-divider"></div>

      <!-- 修改为 Element Plus 按钮组，仅显示图标 -->
      <el-button-group class="toolbar-button-group">
        <el-tooltip
          content="撤销 (Ctrl+Z)"
          placement="bottom"
          :show-after="100">
          <el-button
            type="default"
            size="small"
            :disabled="!canUndo"
            @click="handleCommand('undo')"
            :icon="Back">
          </el-button>
        </el-tooltip>
        <el-tooltip
          content="恢复 (Ctrl+Y)"
          placement="bottom"
          :show-after="100">
          <el-button
            type="default"
            size="small"
            :disabled="!canRedo"
            @click="handleCommand('redo')"
            :icon="Right">
          </el-button>
        </el-tooltip>
        <el-tooltip
          content="重新绘制"
          placement="bottom"
          :show-after="100">
          <el-button
            type="default"
            size="small"
            @click="handleCommand('redraw')"
            :icon="Refresh">
          </el-button>
        </el-tooltip>
      </el-button-group>

      <div class="toolbar-divider"></div>

      <!-- 修改为 Element Plus 按钮组，仅显示图标 -->
      <el-button-group class="toolbar-button-group">
        <el-tooltip
          content="放大视图 (+)"
          placement="bottom"
          :show-after="100">
          <el-button
            type="default"
            size="small"
            @click="handleCommand('zoomIn')"
            :icon="Plus">
          </el-button>
        </el-tooltip>
        <el-tooltip
          content="缩小视图 (-)"
          placement="bottom"
          :show-after="100">
          <el-button
            type="default"
            size="small"
            @click="handleCommand('zoomOut')"
            :icon="Minus">
          </el-button>
        </el-tooltip>
        <el-tooltip
          content="重置视图 (Ctrl+0)"
          placement="bottom"
          :show-after="100">
          <el-button
            type="default"
            size="small"
            @click="handleCommand('resetZoom')"
            :icon="ScaleToOriginal">
          </el-button>
        </el-tooltip>
      </el-button-group>

      <!-- 移除了原来的文件操作图标按钮组 -->
    </div>
  </div>

  <!-- BPMN XML预览对话框 -->
  <el-dialog
    v-model="dialogVisible"
    title="BPMN XML预览"
    width="60%"
    :close-on-click-modal="false"
    :close-on-press-escape="true">
    <div class="xml-preview-container">
      <pre class="xml-content" v-html="xmlContent"></pre>
    </div>
  </el-dialog>

  <!-- 流程校验结果悬浮面板 -->
  <div
    v-if="validateDialogVisible"
    class="validate-result-floating-panel"
    ref="validatePanel">
    <div class="validate-result-header">
      <div class="validate-result-title">
        流程校验结果
        <el-switch
          v-model="validateEnabled"
          active-text="开启校验"
          inactive-text="关闭校验"
          size="small"
          style="margin-left: 10px;"
        />
      </div>
      <el-button
        type="text"
        class="close-button"
        @click="validateDialogVisible = false">
        <el-icon><Close /></el-icon>
      </el-button>
    </div>
    <div class="validate-result-container">
      <div v-if="validateResults.length === 0" class="validate-success">
        <el-icon class="success-icon"><CircleCheckFilled /></el-icon>
        <span>校验通过，流程符合规范要求</span>
      </div>
      <div v-else class="validate-error">
        <el-collapse>
          <el-collapse-item
            v-for="(result, index) in validateResults"
            :key="index"
            :title="result.title"
            :name="index">
            <template #title>
              <div class="result-item-title">
                <span class="result-index">{{ index + 1 }}.</span>
                <el-icon class="error-icon"
                  ><WarningFilled
                /></el-icon>
                <span>{{ result.title }}</span>
              </div>
            </template>
            <div class="error-detail">
              <p class="error-message">{{ result.message }}</p>
              <el-button
                v-if="result.elementId"
                type="primary"
                size="small"
                @click="locateElement(result.elementId,false)">
                定位元素
              </el-button>
            </div>
          </el-collapse-item>
        </el-collapse>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref, onMounted } from 'vue';
import {
  ElIcon,
  ElDialog,
  ElMessage,
  ElTooltip,
  ElCollapse,
  ElCollapseItem,
  ElButton,
  ElButtonGroup
} from 'element-plus';
import {
  Back, // 撤销图标 - 更直观的返回概念
  Right, // 恢复图标 - 前进/重做的概念
  Plus, // 放大图标 - 加号更直观
  Minus, // 缩小图标 - 减号更直观
  ScaleToOriginal, // 重置视图图标 - 更准确的缩放重置
  Refresh, // 重新绘制保持不变
  FolderOpened, // 导入文件图标 - 打开文件夹更直观
  Download, // 导出文件保持不变
  Monitor, // 预览图标 - 显示器/预览更合适
  Document, // 保存图标保持不变
  Check, // 校验图标
  CircleCheckFilled, // 校验成功图标
  WarningFilled, // 校验警告图标
} from '@element-plus/icons-vue';
import hljs from 'highlight.js';
import 'highlight.js/styles/github.css';
import { defaultXml } from '../config';
import { createProcessValidator } from '../utils/processValidator';
import type { ValidationResult } from '../utils/processValidator';

const props = defineProps<{
  modeler: any;
}>();

// 定义事件发射
const emit = defineEmits<{
  (e: 'save', xml: string): void;
}>();

const canUndo = ref(false);
const canRedo = ref(false);
const dialogVisible = ref(false);
const validateDialogVisible = ref(false);
const xmlContent = ref('');
const fileInput = ref<HTMLInputElement>();
const validateResults = ref<ValidationResult[]>([]);
let processValidator: any = null;

// 处理命令
const handleCommand = (command: string) => {
  if (!props.modeler) return;

  switch (command) {
    case 'undo':
      if (!canUndo.value) return; // 添加状态检查
      {
        const commandStack = props.modeler.get('commandStack');
        if (commandStack) commandStack.undo();
      }
      break;
    case 'redo':
      if (!canRedo.value) return; // 添加状态检查
      {
        const commandStack = props.modeler.get('commandStack');
        if (commandStack) commandStack.redo();
      }
      break;
    case 'zoomIn':
      {
        const canvas = props.modeler.get('canvas');
        if (canvas) canvas.zoom(canvas.zoom() + 0.1);
      }
      break;
    case 'zoomOut':
      {
        const canvas = props.modeler.get('canvas');
        if (canvas) canvas.zoom(canvas.zoom() - 0.1);
      }
      break;
    case 'resetZoom':
      {
        const canvas = props.modeler.get('canvas');
        if (canvas) canvas.zoom('fit-viewport');
      }
      break;
    case 'save':
      saveXML();
      break;
    case 'download':
      downloadXML();
      break;
    case 'preview':
      previewBPMN();
      break;
    case 'import':
      fileInput.value?.click();
      break;
    case 'redraw':
      redrawBPMN();
      break;
    case 'validate':
      validateProcess();
      break;
  }
};

// 重新绘制BPMN
const redrawBPMN = async () => {
  if (!props.modeler) {
    console.error('modeler未初始化');
    return;
  }
  try {
    // 清空画布并重新导入
    await props.modeler.clear();
    await props.modeler.importXML(defaultXml);
    // 重置视图
    const canvas = props.modeler.get('canvas');
    canvas.zoom('fit-viewport');
    ElMessage.success('重新绘制成功');
  } catch (err) {
    console.error('重新绘制失败', err);
    ElMessage.error('重新绘制失败');
  }
};

// 处理文件选择
const handleFileChange = async (event: Event) => {
  const input = event.target as HTMLInputElement;
  const file = input.files?.[0];
  if (!file) return;

  try {
    const reader = new FileReader();
    reader.onload = async (e) => {
      const xml = e.target?.result;
      if (typeof xml === 'string') {
        try {
          // 导入 XML 到编辑器
          await props.modeler.importXML(xml);
          // 重置视图
          const canvas = props.modeler.get('canvas');
          canvas.zoom('fit-viewport');
        } catch (err) {
          console.error('导入失败', err);
          ElMessage.error('导入失败，请检查文件格式是否正确');
        }
      }
    };
    reader.readAsText(file);
  } catch (err) {
    console.error('读取文件失败', err);
    ElMessage.error('读取文件失败');
  } finally {
    // 清空文件输入框的值，以便可以重复导入同一个文件
    input.value = '';
  }
};

// 预览BPMN XML
const previewBPMN = async () => {
  if (!props.modeler) {
    console.error('modeler未初始化');
    return;
  }
  try {
    const { xml } = await props.modeler.saveXML({ format: true });
    xmlContent.value = hljs.highlight(xml, { language: 'xml' }).value;
    dialogVisible.value = true;
  } catch (err) {
    console.error('预览失败', err);
  }
};

// 检查流程是否有校验错误
const hasValidationErrors = () => {
  // 如果校验功能关闭，则不检查错误
  if (!validateEnabled.value) {
    return false;
  }

  // 如果没有校验结果，需要先执行校验
  if (validateResults.value.length === 0) {
    // 创建流程校验器但不显示UI
    if (props.modeler) {
      processValidator = createProcessValidator(props.modeler);
      const results = processValidator.validateAll(false);
      return results.length > 0;
    }
    return false;
  }

  // 检查是否有错误级别的校验结果
  return validateResults.value.length > 0;
};

// 保存XML
const saveXML = async () => {
  if (!props.modeler) {
    console.error('modeler未初始化');
    return;
  }

  // 检查是否有校验错误
  if (hasValidationErrors()) {
    ElMessage.error('流程存在校验错误，无法保存');
    // 如果校验结果窗口未显示，则显示它
    if (!validateDialogVisible.value) {
      validateProcess();
    }
    return;
  }

  const { xml } = await props.modeler.saveXML({ format: true });
  // 发射保存事件
  emit('save', xml);
  ElMessage.success('保存成功');
};

// 下载XML
const downloadXML = async () => {
  if (!props.modeler) {
    console.error('modeler未初始化');
    return;
  }
  try {
    const { xml } = await props.modeler.saveXML({ format: true });
    let content: string = xml || '';
    let name: string = 'diagram.xml';
    const blob = new Blob([content], { type: 'application/octet-stream' });
    const url = window.URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.download = name;
    link.click();
    window.URL.revokeObjectURL(url);
  } catch (err) {
    console.error(err);
  }
};

// 是否启用校验
const validateEnabled = ref(true);

// 校验流程
const validateProcess = async () => {
  if (!props.modeler) {
    console.error('modeler未初始化');
    return;
  }

  // 如果校验被禁用，直接返回
  if (!validateEnabled.value) {
    ElMessage.info('流程校验功能已关闭');
    return;
  }

  try {
    // 清空之前的校验结果
    validateResults.value = [];
    // 创建流程校验器
    processValidator = createProcessValidator(props.modeler);
    // 执行校验，传入true参数，自动为所有问题节点添加警告样式
    validateResults.value = processValidator.validateAll(true);
    // 显示校验结果对话框
    validateDialogVisible.value = true;
    // 如果没有错误，显示成功消息
    if (validateResults.value.length === 0) {
      ElMessage.success('流程校验通过');
    } else {
      // 统计不同严重程度的问题数量
      const errorCount = validateResults.value.length;
      if (errorCount > 0) {
        ElMessage.error(
          `校验发现 ${errorCount} 个错误`
        );
      }
    }
  } catch (err) {
    console.error('校验流程失败', err);
    ElMessage.error('校验流程失败');
  }
};

// 定位到指定元素
const locateElement = (elementId: string, closeDialog: boolean = true) => {
  if (!processValidator || !elementId) return;

  try {
    // 使用校验器的定位方法
    processValidator.locateElement(elementId);

    // 根据参数决定是否关闭对话框
    if (closeDialog) {
      validateDialogVisible.value = false;
    }
  } catch (err) {
    console.error('定位元素失败', err);
  }
};

// 监听命令栈变化
onMounted(() => {
  if (props.modeler) {
    const commandStack = props.modeler.get('commandStack');
    if (commandStack) {
      commandStack._eventBus.on('commandStack.changed', () => {
        canUndo.value = commandStack.canUndo();
        canRedo.value = commandStack.canRedo();
      });
    }
  }
});
</script>

<style lang="scss" scoped>
.process-toolbar {
  width: 100%;
  height: 35px;
  background: #ffffff; // 纯白背景
  border-bottom: 1px solid #e5e7eb; // 简化边框颜色
  display: flex;
  align-items: center;
  padding: 0 16px;
  user-select: none;
  position: relative;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.03); // 极微的阴影
  z-index: 50;
}

.toolbar-container {
  display: flex;
  align-items: center;
  width: 100%;
}

.toolbar-group {
  display: flex;
  align-items: center;
  gap: 4px; // 适中的间距

  .toolbar-item {
    width: 36px; // 稍微增加尺寸
    height: 36px;
    border-radius: 6px; // 适中的圆角
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: all 0.2s ease; // 简化过渡效果
    position: relative;
    background: transparent; // 默认透明背景
    border: none; // 移除边框

    &:hover {
      background: rgba(0, 0, 0, 0.04); // 浅灰色悬停背景
      border-radius: 6px;
    }

    &:active {
      background: rgba(0, 0, 0, 0.08); // 点击时稍深的背景
    }

    &.disabled {
      cursor: not-allowed;
      opacity: 0.4;

      &:hover {
        background: transparent;
      }

      .el-icon {
        color: #9ca3af;
      }
    }

    .el-icon {
      font-size: 20px;
      color: #374151; // 深灰色图标
      transition: color 0.2s ease;
      font-weight: 500; // 适中的字体粗细
    }

    &:hover:not(.disabled) .el-icon {
      color: #1f2937; // hover时稍深的颜色
    }
  }
}

.toolbar-divider {
  width: 1px;
  height: 20px;
  background: #e5e7eb; // 简单的灰色分隔线
  margin: 0 12px;
}

// Element Plus 按钮组样式优化
.toolbar-button-group {
  :deep(.el-button) {
    height: 32px;
    padding: 8px 12px;
  }

  // 确保首尾按钮圆角正确显示
  :deep(.el-button:first-child) {
    border-top-left-radius: 4px;
    border-bottom-left-radius: 4px;
  }

  :deep(.el-button:last-child) {
    border-top-right-radius: 4px;
    border-bottom-right-radius: 4px;
  }
}

.xml-preview-container {
  background: #f8f9fa;
  border-radius: 8px;
  padding: 16px;
  max-height: 600px;
  overflow: auto;
  border: 1px solid #e5e7eb;
}

.xml-content {
  margin: 0;
  font-family:
    'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New',
    monospace;
  font-size: 14px;
  line-height: 1.6;
  white-space: pre-wrap;
  word-wrap: break-word;
  color: #374151;
  background: #ffffff;
  padding: 12px;
  border-radius: 6px;
  border: 1px solid #e5e7eb;
}

// 悬浮校验结果面板样式
.validate-result-floating-panel {
  position: absolute;
  left: 5px;
  bottom: 5px;
  width: 350px;
  max-height: 500px;
  background-color: #fff;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  z-index: 1000;
  display: flex;
  flex-direction: column;
  overflow: hidden;

  .validate-result-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 16px;
    background-color: #f5f7fa;
    border-bottom: 1px solid #e4e7ed;

    .validate-result-title {
      font-weight: bold;
      font-size: 16px;
      color: #303133;
    }

    .close-button {
      padding: 2px;
    }
  }
}

// 校验结果样式
.validate-result-container {
  padding: 16px;
  max-height: 450px;
  overflow: auto;

  .validate-success {
    display: flex;
    align-items: center;
    padding: 20px;
    background-color: #f0f9eb;
    border-radius: 8px;

    .success-icon {
      font-size: 24px;
      color: #67c23a;
      margin-right: 12px;
    }

    span {
      font-size: 16px;
      color: #67c23a;
      font-weight: 500;
    }
  }

  .validate-error {
    .error-header {
      margin-bottom: 16px;

      .error-summary {
        display: flex;
        flex-wrap: wrap;
        gap: 12px;

        .error-count,
        .warning-count,
        .info-count {
          display: flex;
          align-items: center;
          padding: 8px 12px;
          border-radius: 6px;

          .el-icon {
            font-size: 18px;
            margin-right: 8px;
          }

          span {
            font-size: 14px;
            font-weight: 500;
          }
        }

        .error-count {
          background-color: #fef0f0;

          .error-icon {
            color: #f56c6c;
          }

          span {
            color: #f56c6c;
          }
        }

        .warning-count {
          background-color: #fdf6ec;

          .warning-icon {
            color: #e6a23c;
          }

          span {
            color: #e6a23c;
          }
        }

        .info-count {
          background-color: #f4f4f5;

          .info-icon {
            color: #909399;
          }

          span {
            color: #909399;
          }
        }
      }
    }

    .result-item-title {
      display: flex;
      align-items: center;

      .el-icon {
        margin-right: 8px;
      }

      .error-icon {
        color: #f56c6c;
      }

      .warning-icon {
        color: #e6a23c;
      }

      .info-icon {
        color: #909399;
      }
    }

    .error-detail {
      padding: 8px 0;

      .error-message {
        margin-bottom: 12px;
        color: #606266;
      }
    }
  }
}

// 响应式设计
@media (max-width: 768px) {
  .process-toolbar {
    height: 40px;
    padding: 0 16px;
  }

  .toolbar-group {
    gap: 4px;

    .toolbar-item {
      width: 32px;
      height: 32px;
      border-radius: 6px;

      .el-icon {
        font-size: 18px;
      }

      &:hover {
        background: rgba(0, 0, 0, 0.04); // 移动端保持简单的悬停效果
      }
    }
  }

  .toolbar-divider {
    margin: 0 8px;
    height: 20px;
  }
}
</style>